#include "glad\glad.h"  
#include "glfw3.h" 
#include <iostream>

void processInput(GLFWwindow *window);
void framebuffer_size_callback(GLFWwindow* window, int width, int height);

// Window dimensions
const GLuint WIDTH = 800, HEIGHT = 600;
// Shaders
const GLchar* vertexShaderSource = "#version 330 core\n"  //顶点着色器源码
"layout (location = 0) in vec3 position;\n"
"out vec4 vertexColor;\n"
"void main()\n"
"{\n"
"gl_Position = vec4(position, 1.0);\n"
"vertexColor = vec4(0.5f, 0.0f, 0.0f, 1.0f);\n"
"}\0";

const GLchar* fragmentShaderSource = "#version 330 core\n"  //片段着色器源码
"out vec4 color;\n"
"uniform vec4 ourColor;\n"
"void main()\n"
"{\n"
"color = ourColor;\n" //前三个是颜色参数， 第四个是alpha透明度1.0f为完全不透明
"}\n\0";


int main() {

	//初始化GLFW
	glfwInit();
	//定义OPEN的版本为3.3
	glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);		//主版本			
	glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);		//次版本
	//使用核心模式
	glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);


	//创建一个Win窗口
	GLFWwindow* window = glfwCreateWindow(800, 600, "OpenGL_01", NULL, NULL);
	glfwMakeContextCurrent(window); //make就出来窗口了

	//每当窗口尺寸发生变化时，重设渲染尺寸
	glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);

	//加载GLAD
	if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress))
	{
		printf("初始化GLAD失败 ！");
		return -1;
	}
	/*--------------------------------------------------------------------*/
	 // 创建一个顶点着色器对象
	//把这个着色器源码附加到着色器对象上，然后编
	GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER); //用glCreateShader创建这个着色器
	glShaderSource(vertexShader, 1, &vertexShaderSource, NULL);
	glCompileShader(vertexShader);
	// 片段着色器shader
	GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
	glShaderSource(fragmentShader, 1, &fragmentShaderSource, NULL);
	glCompileShader(fragmentShader);

	// 链接shaders
	GLuint shaderProgram = glCreateProgram();
	glAttachShader(shaderProgram, vertexShader);
	glAttachShader(shaderProgram, fragmentShader);
	glLinkProgram(shaderProgram); 
	
	glUseProgram(shaderProgram);//激活
	//删除前面连个对象
	glDeleteShader(vertexShader);
	glDeleteShader(fragmentShader);
	/*----------------------------------------------------------------------*/

	GLfloat firstTriangle[] = {
	   -0.9f, -0.5f, 0.0f,  // Left 
	   -0.0f, -0.5f, 0.0f,  // Right
	   -0.45f, 0.5f, 0.0f,  // Top 
	};
	GLfloat secondTriangle[] = {
		 0.0f, -0.5f, 0.0f,  // Left
		 0.9f, -0.5f, 0.0f,  // Right
		 0.45f, 0.5f, 0.0f   // Top 
	};
	GLuint VBOs[2], VAOs[2];

	glGenVertexArrays(2, VAOs);
	glGenBuffers(2, VBOs);

	// ================================
	// First Triangle setup
	// ===============================
	glBindVertexArray(VAOs[0]);
	glBindBuffer(GL_ARRAY_BUFFER, VBOs[0]);
	glBufferData(GL_ARRAY_BUFFER, sizeof(firstTriangle), firstTriangle, GL_STATIC_DRAW);
	glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), (GLvoid*)0);	// Vertex attributes stay the same
	glEnableVertexAttribArray(0);
	glBindVertexArray(0);
	// ================================
   // Second Triangle setup
   // ===============================
	glBindVertexArray(VAOs[1]);	// Note that we bind to a different VAO now
	glBindBuffer(GL_ARRAY_BUFFER, VBOs[1]);	// And a different VBO
	glBufferData(GL_ARRAY_BUFFER, sizeof(secondTriangle), secondTriangle, GL_STATIC_DRAW);
	glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, (GLvoid*)0); // Because the vertex data is tightly packed we can also specify 0 as the vertex attribute's stride to let OpenGL figure it out.
	glEnableVertexAttribArray(0);
	glBindVertexArray(0);



	// 渲染循环
	while (!glfwWindowShouldClose(window))
	{
		// 输入
		processInput(window);
		//glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
		// 检查并调用事件
		glfwPollEvents();

		// 擦黑板 （底色）
		glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
		glClear(GL_COLOR_BUFFER_BIT);

		// Draw our first triangle
		glUseProgram(shaderProgram);

		GLfloat timeValue = glfwGetTime();
		GLfloat greenValue = (sin(timeValue) / 2) + 0.5;
		GLint vertexColorLocation = glGetUniformLocation(shaderProgram, "ourColor");
		glUniform4f(vertexColorLocation, 0.0f, greenValue, 0.0f, 1.0f);

		// Draw first triangle using the data from the first VAO
		glBindVertexArray(VAOs[0]);
		glDrawArrays(GL_TRIANGLES, 0, 3);
		// Then we draw the second triangle using the data from the second VAO
		glBindVertexArray(VAOs[1]);
		glDrawArrays(GL_TRIANGLES, 0, 3);


		glBindVertexArray(0);


		// 交换缓冲
		glfwSwapBuffers(window);
	}
	glDeleteVertexArrays(2, VAOs);
	glDeleteBuffers(2, VBOs);

	//释放
	glfwTerminate();
	return 0;
}

//渲染尺寸调整
void framebuffer_size_callback(GLFWwindow* window, int width, int height)
{
	glViewport(0, 0, width, height);
}

//按下ESC键退出
void processInput(GLFWwindow *window)
{
	if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)
		glfwSetWindowShouldClose(window, true);
}
